package webservice;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import sessions.IUserAccountSession;
import util.Validator;

/**
 * Trabalho PD - 2014/2015
 *
 * @author a21210380 a21210392
 */
@WebService(name = "AccountWebService", serviceName = "AccountWebService")
public class AccountWebService {

    @Inject
    private IUserAccountSession userAccountSession;

    @WebMethod(operationName = "login")
    public String login(@WebParam(name = "username") String username, @WebParam(name = "password") String password) {
        return "{\"success\":" + (userAccountSession.login(username, password) ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "logout")
    public String logout() {
        return "{\"success\":" + (userAccountSession.logout() ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "registerUser")
    public String registerUser(
            @WebParam(name = "userNameField") String userNameField, @WebParam(name = "passwordField") String passwordField,
            @WebParam(name = "nameField") String nameField, @WebParam(name = "identityNumberField") int identityNumberField,
            @WebParam(name = "emailField") String emailField, @WebParam(name = "id_country") int id_country,
            @WebParam(name = "id_address") int id_address, @WebParam(name = "welcomeMessageField") String welcomeMessageField,
            @WebParam(name = "numberSeatsField") int numberSeatsField, @WebParam(name = "plateNumberField") String plateNumberField,
            @WebParam(name = "brandField") String brandField, @WebParam(name = "yearField") int yearField) {
        return "{\"success\":" + (userAccountSession.registerUser(userNameField, passwordField, nameField, identityNumberField, emailField, id_country, id_address, welcomeMessageField, numberSeatsField, plateNumberField, brandField, yearField) ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "editUser")
    public String editUser(@WebParam(name = "passwordField") String passwordField,
            @WebParam(name = "nameField") String nameField, @WebParam(name = "identityNumberField") int identityNumberField,
            @WebParam(name = "emailField") String emailField, @WebParam(name = "id_country") int id_country,
            @WebParam(name = "id_address") int id_address) {
        return "{\"success\":" + (userAccountSession.editUser(passwordField, nameField, identityNumberField, emailField, id_country, id_address) ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "editAdmin")
    public String editAdmin(@WebParam(name = "passwordField") String passwordField,
            @WebParam(name = "nameField") String nameField, @WebParam(name = "identityNumberField") int identityNumberField,
            @WebParam(name = "emailField") String emailField) {
        return "{\"success\":" + (userAccountSession.editAdmin(passwordField, nameField, identityNumberField, emailField) ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "createTrip")
    public String createTrip(
            @WebParam(name = "departueDate") String departueDate, @WebParam(name = "arrivalDate") String arrivalDate,
            @WebParam(name = "description") String description, @WebParam(name = "id_car") int id_car,
            @WebParam(name = "id_starting_country") int id_starting_country, @WebParam(name = "id_starting_address") int id_starting_address,
            @WebParam(name = "id_ending_country") int id_ending_country, @WebParam(name = "id_ending_address") int id_ending_address) {

        return "{\"success\":" + (userAccountSession.createTrip(Validator.parseDate(departueDate), Validator.parseDate(arrivalDate), description, id_car, id_starting_country, id_starting_address, id_ending_country, id_ending_address) ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "createAddress")
    public String createAddress(
            @WebParam(name = "countryName") String countryName, @WebParam(name = "address") String address,
            @WebParam(name = "lat") String lat, @WebParam(name = "lng") String lng) {
        return "{\"success\":" + (userAccountSession.createAddress(countryName, address, lat, lng) ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "createCar")
    public String createCar(
            @WebParam(name = "numberSeatsField") int numberSeatsField, @WebParam(name = "plateNumberField") String plateNumberField,
            @WebParam(name = "brandField") String brandField, @WebParam(name = "yearField") int yearField) {
        return "{\"success\":" + userAccountSession.createCar(numberSeatsField, plateNumberField, brandField, yearField) + "}";
    }

    @WebMethod(operationName = "editCar")
    public String editCar(
            @WebParam(name = "car_id") int car_id,
            @WebParam(name = "numberSeatsField") int numberSeatsField, @WebParam(name = "plateNumberField") String plateNumberField,
            @WebParam(name = "brandField") String brandField, @WebParam(name = "yearField") int yearField) {
        return "{\"success\":" + userAccountSession.editCar(car_id, numberSeatsField, plateNumberField, brandField, yearField) + "}";
    }

    @WebMethod(operationName = "removeCar")
    public String removeCar(@WebParam(name = "car_id") int car_id) {
        return "{\"success\":" + (userAccountSession.deleteCar(car_id) ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "activateWaitingAccount")
    public String activateWaitingAccount(@WebParam(name = "user_id") int user_id) {
        return "{\"success\":" + (userAccountSession.activateWaitingAccount(user_id) ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "activateCancelledAccount")
    public String activateCancelledAccount(@WebParam(name = "user_id") int user_id) {
        return "{\"success\":" + (userAccountSession.activateCancelledAccount(user_id) ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "requestCancelledAccountReactivation")
    public String requestCancelledAccountReactivation() {
        return "{\"success\":" + (userAccountSession.requestCancelledAccountReactivation() ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "cancelAccount")
    public String cancelAccount(@WebParam(name = "reason") String reason) {
        return "{\"success\":" + (userAccountSession.cancelAccount(reason) ? "true" : "false") + "}";
    }
    
    @WebMethod(operationName = "joinTrip")
    public String joinTrip(@WebParam(name = "id_trip") int id_trip) {
        return "{\"success\":" + (userAccountSession.joinTrip(id_trip) ? "true" : "false") + "}";
    }
    
    @WebMethod(operationName = "acceptUserInTrip")
    public String acceptUserInTrip(@WebParam(name = "id_trip") int id_trip, @WebParam(name = "user_id") int user_id) {
        return "{\"success\":" + (userAccountSession.acceptUserInTrip(id_trip, user_id) ? "true" : "false") + "}";
    }

    @WebMethod(operationName = "evaluate")
    public String evaluate(@WebParam(name = "id_trip") int id_trip, @WebParam(name = "car_eval") String car_eval, @WebParam(name = "driver_eval") String driver_eval, @WebParam(name = "passenger_eval") String passenger_eval) {
        Map<String, Integer> carEvaluation = new HashMap<>();
        try {
            JsonReader reader = Json.createReader(new StringReader(car_eval));
            JsonObject obj = reader.readObject();
            if (!obj.containsKey("id_car") || !obj.containsKey("cleanliness") || !obj.containsKey("safety") || !obj.containsKey("conservation")) {
                return "{\"success\":false}";
            }
            carEvaluation.put("id_car", obj.getInt("id_car"));
            carEvaluation.put("cleanliness", obj.getInt("cleanliness"));
            carEvaluation.put("safety", obj.getInt("safety"));
            carEvaluation.put("conservation", obj.getInt("conservation"));
        } catch (Exception ex) {
            return "{\"success\":false}";
        }

        Map<String, Integer> driverEvaluation = new HashMap<>();
        if (driver_eval != null && !driver_eval.isEmpty() && !driver_eval.equals("null")) {
            try {
                JsonReader reader = Json.createReader(new StringReader(driver_eval));
                JsonObject obj = reader.readObject();
                if (!obj.containsKey("id_driver") || !obj.containsKey("courtesy") || !obj.containsKey("punctuality") || !obj.containsKey("driveCarefully")) {
                    return "{\"success\":false}";
                }
                driverEvaluation.put("id_driver", obj.getInt("id_driver"));
                driverEvaluation.put("courtesy", obj.getInt("courtesy"));
                driverEvaluation.put("punctuality", obj.getInt("punctuality"));
                driverEvaluation.put("driveCarefully", obj.getInt("driveCarefully"));
            } catch (Exception ex) {
                return "{\"success\":false}";
            }
        }

        Map<Integer, Map<String, Integer>> evaluations = new HashMap<>();
        try {
            JsonReader reader = Json.createReader(new StringReader(passenger_eval));
            JsonArray readArray = reader.readArray();
            for (JsonValue v : readArray) {
                JsonObject obj = (JsonObject)v;
                Map<String, Integer> map = new HashMap<>();
                if (!obj.containsKey("goodHumored") || !obj.containsKey("punctuality")) {
                    return "{\"success\":false}";
                }
                map.put("goodHumored", obj.getInt("goodHumored"));
                map.put("punctuality", obj.getInt("punctuality"));
                map.put("id_passenger", obj.getInt("id_passenger"));
                evaluations.put(obj.getInt("id_passenger"), map);
            }
        } catch (Exception ex) {
            return "{\"success\":false}";
        }
        return "{\"success\":" + (userAccountSession.evaluate(id_trip, driverEvaluation, carEvaluation, evaluations) ? "true" : "false") + "}";
    }
    
    
}
